package cn.ronghuanet.auth.service.impl;

import cn.ronghuanet.auth.dto.LoginDTO;
import cn.ronghuanet.auth.service.ILoginService;
import cn.ronghuanet.base.constants.WxConstants;
import cn.ronghuanet.base.exception.ResponseCode;
import cn.ronghuanet.base.exception.RonghuaAssert;
import cn.ronghuanet.base.util.HttpUtil;
import cn.ronghuanet.base.util.LoginContext;
import cn.ronghuanet.base.util.MD5Utils;
import cn.ronghuanet.org.domain.Employee;
import cn.ronghuanet.org.mapper.EmployeeMapper;
import cn.ronghuanet.user.domain.Logininfo;
import cn.ronghuanet.user.domain.Wxuser;
import cn.ronghuanet.user.mapper.LogininfoMapper;
import cn.ronghuanet.user.mapper.WxuserMapper;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements ILoginService {

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private WxuserMapper wxuserMapper;

    @Override
    public Map<String, Object> login(LoginDTO user) {
        // 1 参数校验
        // 1.1 校验type不能为空
        RonghuaAssert.isNotNull(user.getType(), ResponseCode.RESPONSE_CODE_500);

        // 2 根据账号和type去t_logininfo表中查询账号是否存在,不存在说明账号错误,返回错误信息
        Logininfo logininfo = logininfoMapper.loadByAccount(user.getAccount(),user.getType());
        RonghuaAssert.isNotNull(logininfo,ResponseCode.RESPONSE_CODE_40023);

        // 3 比对密码,密码不正确说明密码错误,返回错误信息
        // 要将传进的密码做MD5加盐加密处理以后,再和数据库作比较
        String salt = logininfo.getSalt();
        String password = MD5Utils.encrypByMd5("ronghuanet"+salt+user.getPassword()+"123456");
        RonghuaAssert.isEq(password,logininfo.getPassword(),ResponseCode.RESPONSE_CODE_40023);

        Map<String, Object> map = loginSuccess(logininfo);
        return map;
    }

    @Override
    public Map<String, Object> wechatLogin(String code) {
        // 1 根据code和appid appserect获取accessToken,openId
        String getAckUrl = WxConstants.GET_ACK_URL.replace("APPID", WxConstants.APPID).replace("SECRET", WxConstants.SECRET)
                .replace("CODE", code);
        // 微信返回的accessToken相关结果  是个json格式的字符串
        String ackStr = HttpUtil.httpGet(getAckUrl);
        // 将字符串转为一个json对象,获取其中的参数
        JSONObject ackObj = JSONObject.parseObject(ackStr);
        // 获取对象中的accessToken&openId
        String accessToken = ackObj.getString("access_token");
        String openid = ackObj.getString("openid");

        // 2 根据openid查询微信用户  t_wxuser
        Wxuser wxuser = wxuserMapper.loadByOpenid(openid);

        // 3 如果微信用户存在,直接做免密登录
        if(Objects.nonNull(wxuser)){
            // 所谓免密登录,其实就是在redis中存入token和logininfo,并且将它们返回给前端
            // 根据userId获取Logininfo对象
            Logininfo logininfo = logininfoMapper.loadByUserId(wxuser.getUserId());
            Map<String, Object> map = loginSuccess(logininfo);
            return map;
        }else{
            // 4 如果不存在,携带accessToken openid跳转到绑定页面
            Map<String,Object> map = new HashMap<>();
            map.put("accessToken",accessToken);
            map.put("openid",openid);
            map.put("message","noBind");
            return map;
        }
    }


    @Override
    public Map<String, Object> loginSuccess(Logininfo logininfo) {
        // 4 将登录信息存入redis中,key->uuid(token) value->logininfo,设置30分钟过期时间
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, logininfo,30, TimeUnit.MINUTES);

        // 5 将token和logininfo信息返回给前端
        Map<String,Object> map = new HashMap<>();
        map.put("token",token);
        // logininfo包含了密码,密码这种敏感信息不能直接返回给前端,让用户有机会看到.,所以敏感信息要清空
        logininfo.setSalt("");
        logininfo.setPassword("");
        map.put("loginUser", logininfo);
        return map;
    }
}
